package com.huitone.smspfm.oldclient.asserver;

import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.huitone.smspfm.oldclient.logger.ExtLogger;

import com.bin.common.utils.DateTimeUtils;
import com.bin.common.utils.StringUtils;
import com.huitone.smspfm.oldclient.app.AppStaticConfigs;
import com.huitone.smspfm.oldclient.core.FileWriter;
import com.huitone.smspfm.oldclient.model.RecvSms;
import com.huitone.smspfm.oldclient.model.ReportSms;
import com.huitone.smspfm.socket.core.handler.DefaultMessageHandler;
import com.huitone.smspfm.socket.core.net.ExtSocket;
import com.huitone.smspfm.socket.protocol.sgip.constant.ErrorCode;
import com.huitone.smspfm.socket.protocol.sgip.message.Message;
import com.huitone.smspfm.socket.protocol.sgip.message.msgbody.Deliver;
import com.huitone.smspfm.socket.protocol.sgip.message.msgbody.Report2;
import com.huitone.smspfm.socket.protocol.sgip.message.msghead.Head;

/**   
* @Title ClientServerMessageHandler.java 
* @Package com.huitone.smspfm.client.core 
* @Description TODO(用一句话描述该文件做什么) 
* @author ybliang   
* @date 2017年4月5日 上午10:53:46 
* @version V1.0   
*/
public class ServerMessageHandler extends DefaultMessageHandler {
	
	private static final ExtLogger logger = ExtLogger.create(ServerMessageHandler.class);
	
	private FileWriter writer = null;
	
	private final ExecutorService executorService = new ThreadPoolExecutor(AppStaticConfigs.shExcutorPoolSize, 
			AppStaticConfigs.shExcutorPoolSize, 1L, TimeUnit.MINUTES, new ArrayBlockingQueue<>(1000), new RejectedExecutionHandler() {
		
		@Override
		public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
			boolean offer = false;
			while(!executor.isShutdown() && !offer) {
				offer = executor.getQueue().offer(r);
				if (!offer) {
					try {
						TimeUnit.MILLISECONDS.sleep(100);
					} catch (InterruptedException e) {}
				}
			}
		}
	});
	
	@Override
	public void handleDeliverMessage(Head head, Deliver body, ExtSocket socket) {
		
		executorService.execute(new Runnable() {
			
			@Override
			public void run() {
				
				Message message = new Message(head, body);
				
				logger.recive(message.toString());
				
				RecvSms recvSms = new RecvSms();
				recvSms.setSerialno(head.getSerialNo());
				recvSms.setClientname(body.getSrvNode());
				recvSms.setMobileno(body.getUserNumber());
				recvSms.setSendport(extractDlvSendport(StringUtils.toString(body.getSendPort())));
				recvSms.setContent(body.getMsgContent());
				recvSms.setCrttime(body.getRecvTime());
				
				try {
					if (writer != null) {
						writer.write(recvSms);
					} else {
						logger.warn("FileWrite为空,打印数据:" + recvSms.toString());
					}
				} catch (IOException e) {
					logger.error("写Deliver信息异常,报告信息:" + recvSms.toString(), e);
				}
				
				socket.response(message, ErrorCode.CODE0);
			}
		});
	}

	@Override
	public void handleReport2Message(Head head, Report2 body, ExtSocket socket) {
		
		executorService.execute(new Runnable() {
			
			@Override
			public void run() {
				
				Message message = new Message(head, body);
				
				logger.report(message.toString());
				
				String orgSerialNo = body.getOrgSerialNo();
				
				List<String> serialNos = StringUtils.splitToList(orgSerialNo, ",");
				
				ReportSms reportSms = new ReportSms();
				reportSms.setMobileno(StringUtils.toString(body.getUserNumber()));
				reportSms.setSendport(extractRptSendport(StringUtils.toString(body.getSendPort())));
				reportSms.setStatus(StringUtils.toString(body.getErrorCode()));
				reportSms.setStatustime(DateTimeUtils.dateToStr2(new Date()));
				reportSms.setClientname(StringUtils.toString(body.getOrgSrvNode()));
				
				for (String serialno:serialNos) {
					reportSms.setSerialno(serialno);
					try {
						if (writer != null) {
							writer.write(reportSms);
						} else {
							logger.warn("FileWrite为空,打印数据:" + reportSms.toString());
						}
					} catch (IOException e) {
						logger.error("写Report信息异常,报告信息:" + reportSms.toString(), e);
					}
				}
				
				socket.response(message, ErrorCode.CODE0);
			}
		});
	}
	
	private String extractRptSendport(String sendport) {
		
		for (int i = 0 ; i < AppStaticConfigs.rptSpExtractRegexs.size() ; i ++) {
			Pattern p = Pattern.compile(StringUtils.toString(AppStaticConfigs.rptSpExtractRegexs.get(i)));
			Matcher m = p.matcher(sendport);
			if (m.find()) {
				int groupCount = m.groupCount();
				int extractGroupIndex = AppStaticConfigs.rptSpExtractRegexsMappingGroup.get(i);
				if (extractGroupIndex <= groupCount) {
					sendport = m.group(extractGroupIndex);
					break;
				}
			}
		}
		
		return sendport;
	}
	
	private String extractDlvSendport(String sendport) {
		
		for (int i = 0 ; i < AppStaticConfigs.dlvSpExtractRegexs.size() ; i ++) {
			Pattern p = Pattern.compile(StringUtils.toString(AppStaticConfigs.dlvSpExtractRegexs.get(i)));
			Matcher m = p.matcher(sendport);
			if (m.find()) {
				int groupCount = m.groupCount();
				int extractGroupIndex = AppStaticConfigs.dlvSpExtractRegexsMappingGroup.get(i);
				if (extractGroupIndex <= groupCount) {
					sendport = m.group(extractGroupIndex);
					break;
				}
			}
		}
		
		return sendport;
	}
	
	@Override
	public void destroy() {
		
		if (executorService != null && !executorService.isShutdown()) {
			executorService.shutdown();
		}
		
		if (writer != null) {
			writer.destroy();
		}
	}

	public FileWriter getWriter() {
		return writer;
	}

	public void setWriter(FileWriter writer) {
		this.writer = writer;
	}
}
